<?php 
namespace town\filter;

use town\base\Filter;
use town\base\Request;
use town\base\Store;

class CSRF implements Filter
{
    /**
     * csrf
     * @param  Request  $request 请求对象
     * @param  callable $next    链
     * @return 响应对象
     */
    public function doFilter(Request $request, callable $next)
    {
        // 验证key && 只需要验证post
        // if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        //     $this->validCSRF($request->post('csrf_token'));
        // }

        // $key = $this->generate();
        return $next($request);
    }


    /**
     * 验证token
     */
    public function validCSRF($token)
    {
        // 需要考虑并行csrf验证,以来源路径判断是否合理
        $token_key = 'csrf_token_'.md5($_SERVER['HTTP_REFERER']);
        $s_token   = $_SESSION[$token_key];

        if (empty($token) || $s_token != $token) {
            return abort(403);
        }
        unset($_SESSION[$token_key]);
        Store::del($token_key);
        Store::del('csrf_token');
        Store::del('csrf_field');
        return true;
    }


    /**
     * 生成token,放入数据仓库
     */
    public function generate()
    {
        $full_url  = $_SERVER['SERVER_NAME'].$_SERVER["REQUEST_URI"];
        if ($_SERVER['HTTPS'] != "on") {
            $full_url = 'http://'.$full_url;
        } else {
            $full_url = 'https://'.$full_url;
        }

        $token_key = 'csrf_token_'.md5($full_url);
        $token_val = md5($token_key.mt_rand());

        $_SESSION[$token_key] = $token_val;
        Store::set($token_key, $token_val);
        Store::set('csrf_token', $token_val);
        Store::set('csrf_field', '<input type="hidden" name="csrf_token" value="'.$token_val.'" />');
        return $token_key;
    }
}
